package bma.common.langutil.jdbc;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import bma.common.langutil.core.Function;
import bma.common.langutil.core.ValueUtil;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 */
public class StatementHelper {

	public static final StatementHelper JDBC = new StatementHelper();

	public int buildParam(FieldValues fvalues, PreparedStatement st, int idx,
			Function<Object, Integer> typeMapper) throws SQLException {
		for (FieldValue fv : fvalues.getFieldValues()) {
			idx = buildParam(fv, st, idx, typeMapper);
		}
		return idx;
	}

	public int buildParam(FieldValue fv, PreparedStatement st, int idx,
			Function<Object, Integer> typeMapper) throws SQLException {
		Object type = fv.getType();
		if (type == CommonFieldValues.CONST)
			return idx;
		int sqlType = typeMapper.apply(type);
		st.setObject(idx++, fv.getValue(), sqlType);
		return idx;
	}

	public boolean buildCriteria(StringBuffer buf, FieldValues fvalues,
			String alias, boolean and) {
		for (FieldValue fv : fvalues.getFieldValues()) {
			and = buildCriteriaField(buf, fv, alias, and);
		}
		return and;
	}

	public boolean buildCriteriaBegin(StringBuffer buf, FieldValue fv,
			String alias, boolean and) {
		if (and) {
			buf.append(" AND ");
		}
		if (ValueUtil.notEmpty(alias)) {
			buf.append(alias).append(".");
		}
		buf.append(fv.getName());
		buf.append(" ");
		buf.append(ValueUtil.notEmpty(fv.getExp()) ? fv.getExp() : "=");
		buf.append(" ");
		return true;
	}

	public boolean buildCriteriaField(StringBuffer buf, FieldValue fv,
			String alias, boolean and) {
		buildCriteriaBegin(buf, fv, alias, and);
		if (fv.getType() == CommonFieldValues.CONST) {
			buf.append(fv.getValue());
		} else {
			buf.append("?");
		}
		return true;
	}

	public String buildInsert(String tableName, FieldValues fvs) {
		StringBuffer buf = new StringBuffer(256);
		buf.append("INSERT INTO ").append(tableName).append(" (");
		boolean and = false;
		for (FieldValue fv : fvs.getFieldValues()) {
			if (and)
				buf.append(",");
			and = true;
			buf.append(fv.getName());
		}
		buf.append(") VALUES (");
		and = false;
		for (FieldValue fv : fvs.getFieldValues()) {
			if (and)
				buf.append(",");
			and = true;
			if (fv.getType() == CommonFieldValues.CONST) {
				buf.append(fv.getValue());
			} else {
				buf.append("?");
			}
		}
		buf.append(")");
		return buf.toString();
	}

	public String buildUpdate(String tableName, FieldValues fvs, FieldValues tj) {
		StringBuffer buf = new StringBuffer(256);
		buf.append("UPDATE ").append(tableName).append(" SET ");
		boolean and = false;
		for (FieldValue fv : fvs.getFieldValues()) {
			if (and)
				buf.append(",");
			and = true;
			buf.append(fv.getName()).append("=");
			if (fv.getType() == CommonFieldValues.CONST) {
				buf.append(fv.getValue());
			} else {
				buf.append("?");
			}
		}
		if (tj.notEmpty()) {
			buf.append(" WHERE ");
			buildCriteria(buf, tj, null, false);
		}
		return buf.toString();
	}

	public String buildDelete(String tableName, FieldValues tj) {
		StringBuffer buf = new StringBuffer(256);
		buf.append("DELETE FROM ").append(tableName);
		if (tj.notEmpty()) {
			buf.append(" WHERE ");
			buildCriteria(buf, tj, null, false);
		}
		return buf.toString();
	}
}
